package com.youkeyi.ddy.cloud.common.aspect;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

import java.lang.reflect.Method;

/**
 * <p>
 *  debug模式的切面，打印出调用方法时的传入参数与执行结果
 * </p>
 *
 * @author 23.1
 * @since 2020-05-11
 */
@Aspect
@Configuration
public class DebugAspect {

    private static final Logger logger = LoggerFactory.getLogger(DebugAspect.class);

    @Value("${system.debug:true}")
    private Boolean isDebugMode;

    @Pointcut("execution(* com.youkeyi.*.*.*..*.*(..)))")
    public void pointCutAt() {

    }

    @Around("pointCutAt()")
    public Object aroundAspect(ProceedingJoinPoint joinPoint) throws Throwable {
        Object result;
        String methodName = null;
        if (isDebugMode) {
            Signature sig = joinPoint.getSignature();
            MethodSignature msig;
            if (sig instanceof MethodSignature) {
                msig = (MethodSignature) sig;
                Object target = joinPoint.getTarget();
                Method currentMethod;
                try {
                    currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
                    methodName = currentMethod.getName();
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (SecurityException e) {
                    e.printStackTrace();
                }
            }
            try {
                if (!joinPoint.getTarget().getClass().getName().contains("com.sun.proxy")) {
                    logger.info(String.format("方法%s-%s开始执行,参数:%s",joinPoint.getTarget().getClass().getName(), methodName, JSON.toJSONString(joinPoint.getArgs(), SerializerFeature.IgnoreNonFieldGetter)));
                }
            } catch (Exception e) {
                logger.info(String.format("方法%s-%s开始执行,参数:不可读取",joinPoint.getTarget().getClass().getName(), methodName));
            }
        }
        try {
            result = joinPoint.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
            if (isDebugMode) {
                logger.info(String.format("方法%s-%s执行异常",joinPoint.getTarget().getClass().getName(), methodName));
            }
            throw e;
        }
        if (isDebugMode) {
            try {
                if (!joinPoint.getTarget().getClass().getName().contains("com.sun.proxy")) {
                    logger.info(String.format("方法%s-%s执行结束,返回值:%s",joinPoint.getTarget().getClass().getName(), methodName, JSON.toJSONString(result, SerializerFeature.IgnoreNonFieldGetter)));
                }
            } catch (Exception e) {
                logger.info(String.format("方法%s-%s执行结束,返回值:不可读取",joinPoint.getTarget().getClass().getName(), methodName));
            }
        }
        return result;
    }
}
